package com.chianghao.rock.system.controller;

import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.stream.Collectors;

import javax.validation.constraints.NotNull;

import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.DeleteMapping;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;

import com.chianghao.auth.web.RequestContext;
import com.chianghao.core.mybatis.plugins.Paging;
import com.chianghao.core.web.R;
import com.chianghao.rock.Constant;
import com.chianghao.rock.admin.system.route.vo.RouteTreeVo;
import com.chianghao.rock.admin.system.user.dto.SetUserRoleDto;
import com.chianghao.rock.admin.system.user.dto.UserAddDto;
import com.chianghao.rock.admin.system.user.dto.UserModifyDto;
import com.chianghao.rock.admin.system.user.vo.UserVo;
import com.chianghao.rock.system.entity.Organization;
import com.chianghao.rock.system.entity.Role;
import com.chianghao.rock.system.entity.Route;
import com.chianghao.rock.system.entity.User;
import com.chianghao.rock.system.service.organization.OrganizationService;
import com.chianghao.rock.system.service.role.RoleService;
import com.chianghao.rock.system.service.user.UserService;
import com.chianghao.rock.utils.TreeUtils;
import com.rock.microshop.common_api.dto.PageDto;
import com.rock.microshop.common_api.vo.PageVo;

import io.swagger.annotations.Api;
import io.swagger.annotations.ApiImplicitParam;
import io.swagger.annotations.ApiImplicitParams;
import io.swagger.annotations.ApiOperation;

@RestController
@RequestMapping("user")
@Api(value="用户",tags={"用户"})
public class UserController {

	@Autowired
	UserService userService;
	
	@Autowired
	OrganizationService organizationService;
	
	@Autowired
	RoleService roleService;
	
	/****
	 * 添加账号
	 * @param dto
	 * @return
	 */
	@PostMapping("add")
	@ApiOperation("添加用户")
	public R<Boolean> addUser(@Validated UserAddDto dto){
		User user = dtoVoUser(dto);
		//校验账号是否存在
		userService.checkHasAccount(dto.getAccount());
		userService.doCreateUser(user,0);
		return R.getSuccess(true);
	}
	
	
	
	@PostMapping("detail")
	@ApiOperation("获取账户详情")
	@ApiImplicitParam(name = "id", value = "主键", paramType = "query", required = true, dataType = "String")
	public R<UserVo> detail(@NotNull(message="error:id,not.null") Long id){
		User user = this.userService.queryOneById(id);
		UserVo userVo = new UserVo();
		BeanUtils.copyProperties(user, userVo);
		return R.getSuccess(userVo);
	}
	
    /**
     * 删除账号
     * @param id
     * @return
     */
	@DeleteMapping("delete")
	@ApiOperation("删除用户")
	@ApiImplicitParam(name = "id", value = "主键", paramType = "query", required = true, dataType = "String")
	public R<Boolean> deleteUser(@NotNull(message="error:id,not.null") Long id){
		this.userService.deleteById(id);
		return R.getSuccess(true);
	}
	
	
	/****
	 * 更新账号
	 * @param dto
	 * @return
	 */
	@PostMapping("modify")
	@ApiOperation("修改用户")
	public R<Boolean> modifyUser(@Validated UserModifyDto dto){
		User user = dtoVoUser(dto);
		if(StringUtils.isNotEmpty(dto.getAccount())) {
			userService.checkHasAccount(dto.getAccount(),dto.getId());
		}
		userService.checkHasAccount(dto.getAccount());
		this.userService.updateById(user, dto.getId());
		return R.getSuccess(true);
	}
	
	/**
	 * 管理员重置密码
	 * @return
	 */
	@PostMapping("reset-password")
	@ApiOperation("修改用户")
	@ApiImplicitParams({
	    @ApiImplicitParam(name="newPassword",value="新密码",required=true,paramType="query"),
	    @ApiImplicitParam(name="id",value="主键",required=true,paramType="query")
	})
	public R<Boolean> setNewPasswordByAdmin(
			@RequestParam("newPassword") @NotNull(message="error:new.password,not.null") String newPassword,
			@RequestParam("id") @NotNull(message="error:id,not.null") String id
	){
		this.userService.doSetNewPassword(id,newPassword);
		return R.getSuccess(true);
	}
	
	/**
	 * 账号分页查询
	 * @param page
	 * @return
	 */
	@GetMapping("page")
	@ApiOperation("分页查新账号信息")
	public R<PageVo<UserVo>> page(PageDto page,Long organizationId,boolean isShowNoOrgUser,String name){
		Paging paging  = new Paging(page.getCurrent(),page.getPageSize()); 
		List<User> list = userService.queryPage(organizationId,isShowNoOrgUser, name,paging);//.queryPage(null,paging);
		Set<Long> orgList  = list.stream().map(item->item.getOrganizationId()).collect(Collectors.toSet());
		Map<Long,Organization> orgMap = this.organizationService.queryOrganizationMap(orgList);
		List<UserVo> items = list.stream().map(item->toUserVo(item,orgMap)).collect(Collectors.toList());
		PageVo<UserVo> p  = new PageVo<UserVo>();
		p.setItems(items);
		p.setTotal(paging.getTotalRows());
		return R.getSuccess(p);
	}
	
	/**
	 * 用户更新自己的密码
	 * @return
	 */
	@PostMapping("modify-password")
	@ApiOperation("修改密码")
	@ApiImplicitParams({
	    @ApiImplicitParam(name="oldPassword",value="旧密码",required=true,paramType="query"),
	    @ApiImplicitParam(name="newPassword",value="新密码",required=true,paramType="query")
	})
	public R<Boolean> updateNewPassword(
			String oldPassword,
			String newPassword
			){
		Long userId  = Long.parseLong(RequestContext.getUserId());
		this.userService.upatePassword(oldPassword,newPassword,userId);
		return R.getSuccess(true);
	}
	
	@ApiOperation("查新用户路由")
	@GetMapping("query-user-route")
	public R<List<RouteTreeVo>> getRouteTree(){
		Long userId  = Long.parseLong(RequestContext.getUserId());
		List<Route> routes = this.userService.queryUserRoute(userId);
		List<RouteTreeVo> volist = TreeUtils.toTreeDto(RouteTreeVo.class, routes, Constant.rootId);
		return R.getSuccess(volist);
	}
	
	@ApiOperation("查新用户路由")
	@GetMapping("user-role")
	public R<List<Long>> getUserRole(Long userId){
		List<Role> list = roleService.queryUserRole(userId);
		List<Long> array  = list.stream().map(item->item.getId()).collect(Collectors.toList());
		return R.getSuccess(array);
	}
	
	
	@ApiOperation("设置用户路由")
	@PostMapping("set-user-role")
	public R<?> setUserRole(@RequestBody SetUserRoleDto dto){
		roleService.doSetUserRole(dto.getUserId(),dto.getRoles());
		return R.getSuccess();
	}

	private User dtoVoUser(UserAddDto dto) {
		User po = new User();
		BeanUtils.copyProperties(dto,po);
		return po;
	}
	private User dtoVoUser(UserModifyDto dto) {
		User po = new User();
		BeanUtils.copyProperties(dto,po);
		return po;
	}
	
	private UserVo toUserVo(User user,Map<Long,Organization> map) {
		UserVo vo = new UserVo();
		BeanUtils.copyProperties(user,vo);
		if(map.containsKey(user.getOrganizationId())&&map.get(user.getOrganizationId())!=null) {
			vo.setOrganizationName(map.get(user.getOrganizationId()).getName());
		}
		return vo;
	}
}
